package com.example.controller;

import com.alibaba.fastjson.JSONObject;
import com.example.annotation.JwtIgnore;
import com.example.common.Result;
import com.example.common.ResultCode;
import com.example.config.shiro.JWTToken;
import com.example.pojo.Audience;
import com.example.pojo.Comment;
import com.example.pojo.User;
import com.example.service.UserCommentService;
import com.example.service.impl.UserServiceImpl;
import com.example.utils.JwtTokenUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.UUID;

@Slf4j
@RestController
@Api(tags = "UserController", description = "管理用户,登录,查找用户等等")

public class UserController {
    @Autowired
    UserServiceImpl userService;
    @Autowired
    Audience audience;
    @Autowired
    UserCommentService commentService;

    @PostMapping("/login")
    @JwtIgnore
    @ApiOperation("登录")
    public Result login(HttpServletResponse response, @RequestBody User user) {
        JSONObject result = new JSONObject();
        Subject subject = SecurityUtils.getSubject();
        String token = JwtTokenUtil.createJWT(user.getPassword(), user.getName(), audience);

        try {
            subject.login(new JWTToken(token));

            // 登录成功 封装用户信息到token
            response.setHeader(JwtTokenUtil.AUTH_HEADER_KEY, JwtTokenUtil.TOKEN_PREFIX + token);
            result.put("token", token);
            Result.SUCCESS(result);
            return Result.SUCCESS(result);
        } catch (UnknownAccountException e) {
            return new Result(ResultCode.USER_NOT_EXIST);
        } catch (IncorrectCredentialsException e) {
            return new Result(ResultCode.USER_LOGIN_ERROR);
        }
    }

    @PostMapping("/signUp")
    @JwtIgnore
    @ApiOperation("注册")
    public Result SignUp(@RequestBody User user, HttpServletResponse response) {
        if (user.getCode() == null) user.setCode("0");
        Result verifyAuthCode = userService.verifyAuthCode(user.getTelephone(), user.getCode());
        if (verifyAuthCode.getMessage().equals("验证码不正确")) {
            return verifyAuthCode;
        }
        JSONObject result = new JSONObject();
        String userId = UUID.randomUUID().toString();
        user.setUuid(userId);
        if (user.getName() != null && user.getPassword() != null) {
            User queryUser = userService.get(user.getName());
            if (queryUser == null) {
                System.out.println(user);
                userService.add(user);
                String jwtToken = JwtTokenUtil.createJWT(user.getPassword(), user.getName(), audience);
                response.setHeader(JwtTokenUtil.AUTH_HEADER_KEY, JwtTokenUtil.TOKEN_PREFIX + jwtToken);
                result.put("token", jwtToken);
                Result.SUCCESS(result);
                return Result.SUCCESS(result);
            }
        } else {
            return new Result(ResultCode.PARAM_TYPE_BIND_ERROR);
        }
        return new Result(ResultCode.USER_HAS_EXISTED);
    }

    @GetMapping("/userinfo")
    @ApiOperation("用户基本信息")
    public Result getUserInfo() {
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        user.setUuid("");
        user.setPassword("");
        return Result.SUCCESS(user);
    }


    @GetMapping("/listUser")
    @RequiresPermissions(value = "user:list")
    public Result<List<User>> listUser(@RequestParam(value = "start", defaultValue = "1") int start,
                                       @RequestParam(value = "size", defaultValue = "10") int size) {
        PageInfo<User> page = null;
        PageHelper.startPage(start, size);
        List<User> users = userService.list();
        for (User user : users) {
            user.setPassword("");
        }
        page = new PageInfo<>(users, 5);
        return Result.SUCCESS(page);
    }

    @PostMapping("/deleteUser")
    @RequiresPermissions("user:delete")
    public Result deleteUser(@RequestBody User user) {
        userService.delete(user.getName());
        return Result.SUCCESS();
    }

    @PostMapping("/updateUser")
    @RequiresPermissions("user:update")
    public Result updateUser(@RequestBody User user) {
        log.info(user.toString());
        userService.update(user);
        return Result.SUCCESS();
    }

    @PostMapping("/submitComment")
    public Result submitComment(@RequestBody Comment comment) {
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        comment.setUuid(user.getUuid());
        commentService.insertSelective(comment);
        return Result.SUCCESS();
    }

    @GetMapping("/getArticleComment")
    public Result getArticleComment(Integer articleId) {
        if (articleId != null) {
            return Result.SUCCESS(commentService.SelectArticleComments(articleId));
        } else return new Result(ResultCode.PARAM_TYPE_BIND_ERROR);
    }

    @GetMapping("/updateGender")
    public Result updateName(@RequestParam("gender") String gender) {
        if (gender.equals("男") || gender.equals("女")) {
            User user = (User) SecurityUtils.getSubject().getPrincipal();
            user.setGender(gender);
            userService.updateGender(user);
            return Result.SUCCESS();
        } else return new Result(ResultCode.PARAM_TYPE_BIND_ERROR);
    }

    @GetMapping("/updateSignature")
    public Result updateSignature(@RequestParam("signature") String signature) {
        if (!signature.equals("") && signature.length() <= 200) {
            User user = (User) SecurityUtils.getSubject().getPrincipal();
            user.setSignature(signature);
            userService.updateSignature(user);
            return Result.SUCCESS();
        } else return new Result(ResultCode.PARAM_TYPE_BIND_ERROR);
    }

    @ApiOperation("获取验证码")
    @GetMapping("/getAuthCode")
    @JwtIgnore
    public Result getAuthCode(@RequestParam String telephone) {
        userService.generateAuthCode(telephone);
        return Result.SUCCESS();
    }

    @ApiOperation("判断验证码是否正确")
    @PostMapping("/verifyAuthCode")
    @JwtIgnore
    public Result verifyAuthCode(@RequestParam String telephone,
                                 @RequestParam String authCode) {
        return userService.verifyAuthCode(telephone, authCode);
    }
}
